<template>
  <el-dialog v-model="visible" :title="title" width="auto">
    <div class="qrcode-view">
      <img :src="qrValue" alt="二维码" ref="qrcodeRef">
      <el-button @click="downloadQrcode" type="primary">下载</el-button>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, nextTick, computed } from 'vue';

// 定义组件属性
interface Props {
  modelValue: boolean;
  qrValue: string;
  title?: string;
}

// 定义事件
interface Emits {
  (e: 'update:modelValue', value: boolean): void;
}

const props = withDefaults(defineProps<Props>(), {
  title: '二维码'
});

const emit = defineEmits<Emits>();

// 控制弹窗显示
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
});

// 二维码引用
const qrcodeRef = ref<HTMLElement | null>(null);

// 下载二维码
const downloadQrcode = async () => {
  if (!qrcodeRef.value) return;
  await nextTick();

  const img = qrcodeRef.value as HTMLImageElement;

  // 创建 canvas
  const canvas = document.createElement('canvas');
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;

  const ctx = canvas.getContext('2d');
  if (!ctx) {
    console.error('无法获取 2D 上下文');
    return;
  }

  // 绘制图片
  ctx.drawImage(img, 0, 0);

  // 导出为 blob
  canvas.toBlob((blob) => {
    if (!blob) {
      console.error('生成图片 blob 失败');
      return;
    }

    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'qrcode.png';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, 'image/png');
};
</script>

<style scoped>
.qrcode-view {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  padding: 20px;
}

.qrcode-view img {
  max-width: 200px;
  max-height: 200px;
  border: 1px solid #e8e8e8;
  border-radius: 8px;
  padding: 10px;
  background: #fff;
}
</style>